#! /usr/bin/python3
# -*- coding: UTF-8 -*-
  
'''※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
File Name: decoration.py
Author: GID5564
Description: 常用装饰器函数，根根需求修改
Version: 1.0
Created Time: 22/08/24-14:01:59
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※'''

import logging
import time
import requests
import concurrent.futures

def concurrent_execute(max_workers=5): 
    '''
    并发执行装饰器，并发执行接口测试，以提高测试效率。
    '''
    def decorator(func): 
        def wrapper(*args, **kwargs): 
            with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: 
                futures = [executor.submit(func, *arg, **kwarg) for arg, kwarg in zip(args, kwargs)] 
                concurrent.futures.wait(futures) 
        return wrapper 
    return decorator

def configure_environment(environment="dev"):   
    '''
    环境配置装饰器，根据不同的环境配置（如开发、测试、生产）调用不同的API端点。
    '''
    environments = {     #根据自己需求更换   
        "dev": "https://dev.example.com",
        "test": "https://test.example.com", 
        "prod": "https://api.example.com"
    }    
    def decorator(func):        
        def wrapper(*args, **kwargs):
            base_url = environments.get(environment, "https://default.example.com")
            kwargs["base_url"] = base_url
            return func(*args, **kwargs)
        return wrapper    
    return decorator

def data_driven_test(test_data): 
    '''
    数据驱动测试装饰器，执行多次接口测试，每次使用不同的测试数据。
    
    @test_data([    
    {"url": "https://example.com/api1"},
    {"url": "https://example.com/api2"}
    ])
    '''
    def decorator(func): 
        def wrapper(): 
            for data in test_data: 
                func(**data) 
        return wrapper 
    return decorator
    

def limit_calls(max_calls_per_minute=60):
    '''
    限制调用频率装饰器，限制接口测试函数的调用频率，避免过载服务器。
    '''
    def decorator(func):
        call_times = []     
        def wrapper(*args, **kwargs):
            current_time = time.time()
            while len(call_times) > 0 and current_time - call_times[0] > 60:
                call_times.pop(0)
            if len(call_times) >= max_calls_per_minute:
                raise Exception("Maximum calls per minute exceeded")
            call_times.append(current_time)
            return func(*args, **kwargs)
        return wrapper    
    return decorator

"""
def validate_decorator(func):
    def wrapper(x, y):
        if isinstance(x, int) and isinstance(y, int):
            return func(x, y)
        else:
            raise ValueError("Input must be integers")
    return wrapper
"""

def validate_params(*param_names, **param_types):    
    '''
    参数验证装饰器，在接口测试中验证输入参数的有效性。    
    '''
    def decorator(func):        
        def wrapper(*args, **kwargs): 
            for name in param_names:
                if name not in kwargs:
                    raise ValueError(f"Missing required parameter: {name}")
            for name, type_ in param_types.items(): 
                if name in kwargs and not isinstance(kwargs[name], type_):  
                    raise TypeError(f"Parameter {name} must be of type {type_.__name__}")
            return func(*args, **kwargs)
        return wrapper    
    return decorator

def validate_status_code(expected_status=200):    
    '''
     验证响应状态码装饰器，确保接口返回预期的状态码。
    '''
    def decorator(func):        
        def wrapper(*args, **kwargs):
            response = func(*args, **kwargs)
            if response.status_code == expected_status: 
                print(f"Status code is as expected: {response.status_code}")
            else:   
                raise Exception(f"Unexpected status code: {response.status_code}")
            return response        
        return wrapper    
    return decorator

def retry(max_retries=3):   
    '''
    重试机制装饰器，当接口测试失败时自动重试一定次数。   
    '''
    def decorator(func):        
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries):
                try:
                    return func(*args, **kwargs)
                except Exception as e: 
                    if attempt < max_retries - 1:  
                        print(f"Attempt {attempt + 1} failed, retrying...") 
                        else:   
                            print(f"Max retries ({max_retries}) reached, last error: {e}")      
                            return None
        return wrapper    
    return decorator
    
def handle_exceptions(func):  
    '''
    异常处理装饰器，捕获并处理接口测试中的异常。    
    '''
    def wrapper(*args, **kwargs):        
        try:            
            return func(*args, **kwargs)
        except Exception as e:            
            print(f"An error occurred in {func.__name__}: {e}")
            return None    
    return wrapper

def measure_time(func): 
    '''
    性能测量装饰器，测量接口测试函数的执行时间。
    '''
    def wrapper(*args, **kwargs): start_time = time.time() 
        result = func(*args, **kwargs) 
        end_time = time.time() 
        print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds to run.") 
        return result 
    return wrapper

def log_function_call(func): 
    '''
    日志记录装饰器，在接口测试中记录每个测试函数的调用情况。
    '''
    def wrapper(*args, **kwargs): 
        logging.basicConfig(level=logging.INFO) 
        logger = logging.getLogger(__name__) 
        logger.info(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}") 
        result = func(*args, **kwargs) 
        logger.info(f"Function {func.__name__} returned: {result}") 
        return result 
    return wrapper
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        